package com.huike.common.utils;

import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.JavaType;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.List;
import java.util.Map;

/**
 * JSON 工具类（基于 Jackson）
 */
public class JsonUtils {

    private static final Logger log = LoggerFactory.getLogger(JsonUtils.class);
    
    // 线程安全的 ObjectMapper
    private static final ObjectMapper objectMapper = createObjectMapper();
    
    // 默认日期格式
    private static final String DEFAULT_DATE_FORMAT = "yyyy-MM-dd HH:mm:ss";
    
    /**
     * 创建并配置 ObjectMapper
     */
    private static ObjectMapper createObjectMapper() {
        ObjectMapper mapper = new ObjectMapper();
        
        // 设置日期格式
        mapper.setDateFormat(new SimpleDateFormat(DEFAULT_DATE_FORMAT));
        
        // 注册 Java 8 时间模块
        mapper.registerModule(new JavaTimeModule());
        
        // 序列化配置
        mapper.setSerializationInclusion(JsonInclude.Include.NON_NULL); // 忽略 null 值
        mapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS); // 不使用时间戳格式
        
        // 反序列化配置
        mapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES); // 忽略未知属性
        mapper.enable(DeserializationFeature.ACCEPT_EMPTY_STRING_AS_NULL_OBJECT); // 空字符串转为 null
        
        return mapper;
    }
    
    /**
     * 对象转 JSON 字符串
     * 
     * @param object 要转换的对象
     * @return JSON 字符串
     */
    public static String toJsonString(Object object) {
        try {
            return objectMapper.writeValueAsString(object);
        } catch (JsonProcessingException e) {
            log.error("对象转JSON失败: {}", e.getMessage());
            throw new RuntimeException("对象转JSON失败", e);
        }
    }
    
    /**
     * 对象转格式化的 JSON 字符串（美化输出）
     * 
     * @param object 要转换的对象
     * @return 格式化的 JSON 字符串
     */
    public static String toPrettyJsonString(Object object) {
        try {
            return objectMapper.writerWithDefaultPrettyPrinter().writeValueAsString(object);
        } catch (JsonProcessingException e) {
            log.error("对象转格式化JSON失败: {}", e.getMessage());
            throw new RuntimeException("对象转格式化JSON失败", e);
        }
    }
    
    /**
     * JSON 字符串转对象
     * 
     * @param json JSON 字符串
     * @param clazz 目标类
     * @param <T> 泛型类型
     * @return 转换后的对象
     */
    public static <T> T parseObject(String json, Class<T> clazz) {
        try {
            return objectMapper.readValue(json, clazz);
        } catch (IOException e) {
            log.error("JSON转对象失败: {}", e.getMessage());
            throw new RuntimeException("JSON转对象失败", e);
        }
    }
    
    /**
     * JSON 字符串转复杂对象（支持泛型）
     * 
     * @param json JSON 字符串
     * @param typeReference 类型引用（如 new TypeReference<List<User>>(){})
     * @param <T> 泛型类型
     * @return 转换后的对象
     */
    public static <T> T parseObject(String json, TypeReference<T> typeReference) {
        try {
            return objectMapper.readValue(json, typeReference);
        } catch (IOException e) {
            log.error("JSON转复杂对象失败: {}", e.getMessage());
            throw new RuntimeException("JSON转复杂对象失败", e);
        }
    }
    
    /**
     * JSON 字符串转 List
     * 
     * @param json JSON 字符串
     * @param clazz List 元素类型
     * @param <T> 泛型类型
     * @return 转换后的 List
     */
    public static <T> List<T> parseList(String json, Class<T> clazz) {
        try {
            JavaType javaType = objectMapper.getTypeFactory()
                    .constructCollectionType(List.class, clazz);
            return objectMapper.readValue(json, javaType);
        } catch (IOException e) {
            log.error("JSON转List失败: {}", e.getMessage());
            throw new RuntimeException("JSON转List失败", e);
        }
    }
    
    /**
     * JSON 字符串转 Map
     * 
     * @param json JSON 字符串
     * @param keyClass Map key 类型
     * @param valueClass Map value 类型
     * @param <K> key 泛型类型
     * @param <V> value 泛型类型
     * @return 转换后的 Map
     */
    public static <K, V> Map<K, V> parseMap(String json, Class<K> keyClass, Class<V> valueClass) {
        try {
            JavaType javaType = objectMapper.getTypeFactory()
                    .constructMapType(Map.class, keyClass, valueClass);
            return objectMapper.readValue(json, javaType);
        } catch (IOException e) {
            log.error("JSON转Map失败: {}", e.getMessage());
            throw new RuntimeException("JSON转Map失败", e);
        }
    }
    
    /**
     * 对象转换为 Map
     * 
     * @param object 要转换的对象
     * @return 转换后的 Map
     */
    public static Map<String, Object> toMap(Object object) {
        return objectMapper.convertValue(object, new TypeReference<Map<String, Object>>() {});
    }
    
    /**
     * Map 转换为对象
     * 
     * @param map 要转换的 Map
     * @param clazz 目标类
     * @param <T> 泛型类型
     * @return 转换后的对象
     */
    public static <T> T mapToObject(Map<?, ?> map, Class<T> clazz) {
        return objectMapper.convertValue(map, clazz);
    }
    
    /**
     * 深拷贝对象
     * 
     * @param object 要拷贝的对象
     * @param clazz 目标类
     * @param <T> 泛型类型
     * @return 拷贝后的新对象
     */
    public static <T> T deepCopy(Object object, Class<T> clazz) {
        String json = toJsonString(object);
        return parseObject(json, clazz);
    }
    
    /**
     * 判断字符串是否为有效 JSON
     * 
     * @param json 要检查的字符串
     * @return 是否为有效 JSON
     */
    public static boolean isValidJson(String json) {
        try {
            objectMapper.readTree(json);
            return true;
        } catch (IOException e) {
            return false;
        }
    }
}